package com.example.freemaker_demo.executer.impl;


import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.resource.ResourceUtil;
import com.example.freemaker_demo.constant.ConstantUtil;
import com.example.freemaker_demo.entity.VueTplEntity;
import com.example.freemaker_demo.executer.TemplateReplacer;
import com.example.freemaker_demo.tools.FreemakerTool;
import com.example.freemaker_demo.tools.TemplateTool;
import lombok.Data;
import lombok.experimental.Accessors;

import java.io.File;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

@Data
@Accessors(chain = true)
public class VueTemplateReplacerImpl implements TemplateReplacer {

    private VueTplEntity vueTplEntity;

    private Map<String, Object> dockerfileMapper = new HashMap<>();
    private Map<String, Object> jenkinsfileMapper = new HashMap<>();
    private Map<String, Object> kubeYamlMapper = new HashMap<>();


    String templateOutputPath;
    String loopTemplateOutputPath;


    @Override
    public void doReplace(String outputDir) {
        templateOutputPath = outputDir;
        loopTemplateOutputPath = templateOutputPath
                + "vueTpl/"
                + vueTplEntity.getContainer().getImageName()
                + "/";

        doReplaceNginx();
        if ("jib".equals(vueTplEntity.getMode())) {
            doReplaceJibYaml();
        } else {
            doReplaceDockerfile();
        }
        doReplaceJenkinsfile();
        doReplaceK8sFiles();
    }

    private void doReplaceNginx() {
        prepareNginx();
        replaceNginx();
    }


    private void doReplaceDockerfile() {
        prepareDockerfile();
        replaceDockerfile();
    }

    private void doReplaceJenkinsfile() {
        prepareJenkinsfileProd();
        replaceJenkinsfileProd();
        prepareJenkinsfileTest();
        replaceJenkinsfileTest();
    }

    private void doReplaceK8sFiles() {
        prepareK8sFilesProd();
        replaceK8sFilesProd();
        prepareK8sFilesTest();
        replaceK8sFilesTest();
    }

    private void doReplaceJibYaml() {
        prepareJibYaml();
        replaceJibYaml();
    }


    private void prepareJibYaml() {
    }


    private void replaceJibYaml() {
        InputStream srcFileNginx = ResourceUtil.getStream("templates/jib.nginx.yaml");
        FileUtil.writeFromStream(srcFileNginx, new File(loopTemplateOutputPath + "jib.yaml"));
    }

    private void prepareNginx() {
    }

    private void replaceNginx() {
        InputStream srcFileNginx = ResourceUtil.getStream("templates/nginx.conf");
        FileUtil.writeFromStream(srcFileNginx, new File(loopTemplateOutputPath + "nginx.conf"));
    }

    private void prepareDockerfile() {
        dockerfileMapper.put("mode", vueTplEntity.getMode() == null ? "" : vueTplEntity.getMode());
        dockerfileMapper.put("profile", "build:prod");
    }

    private void replaceDockerfile() {
        FreemakerTool.generateFile(loopTemplateOutputPath + "Dockerfile",
                "Dockerfile.nginx.ftl",
                dockerfileMapper);
    }

    private void prepareJenkinsfileProd() {
        String kubeConfig = TemplateTool.getKubeConfig(vueTplEntity.getK8s().getCluster());
        String allImageName = TemplateTool.getRepoAddress(vueTplEntity.getK8s().getCluster());
        String tagsCommand = TemplateTool.prepareTagsCommand(vueTplEntity.getContainer().getExtraTag().getTagName(),
                vueTplEntity.getContainer().getExtraTag().getEnable(), false);

        jenkinsfileMapper.put("profile", "build:prod");
        jenkinsfileMapper.put("tagCommand", tagsCommand);
        jenkinsfileMapper.put("cluster", vueTplEntity.getK8s().getCluster());
        jenkinsfileMapper.put("env", "prod");
        jenkinsfileMapper.put("yamlFile", vueTplEntity.getK8s().getDeployName() + "-deploy.yaml");
        jenkinsfileMapper.put("namespace", vueTplEntity.getK8s().getNamespace());
        jenkinsfileMapper.put("deploymentName", vueTplEntity.getK8s().getDeployName());
        jenkinsfileMapper.put("msg", vueTplEntity.getDingMsg());
        jenkinsfileMapper.put("mode", vueTplEntity.getMode() == null ? "" : vueTplEntity.getMode());
        jenkinsfileMapper.put("kubeconfig", kubeConfig);
        jenkinsfileMapper.put("allImageName", allImageName + vueTplEntity.getContainer().getImageName());
        jenkinsfileMapper.put("allImageNameBuild", ConstantUtil.allImageNameBuild + vueTplEntity.getContainer().getImageName());
        jenkinsfileMapper.put("k8sYamlDir", vueTplEntity.getK8s().getK8sYamlDir());
        jenkinsfileMapper.put("repoCredential", "acr-repo");
        jenkinsfileMapper.put("dockerRepoAddress", ConstantUtil.ACRAddress);
        jenkinsfileMapper.put("imageName", ConstantUtil.ACRAddress + "/softwise/" + vueTplEntity.getContainer().getImageName());
        jenkinsfileMapper.put("imageTag", "");
    }

    private void prepareJenkinsfileTest() {
        String tagsCommand = TemplateTool.prepareTagsCommand(vueTplEntity.getContainer().getExtraTag().getTagName(),
                vueTplEntity.getContainer().getExtraTag().getEnable(), true);
        String testYamlDir = vueTplEntity.getK8s().getK8sYamlDir().replace("prod", "test");

        jenkinsfileMapper.put("dockerRepoAddress", ConstantUtil.harborAddress);
        jenkinsfileMapper.put("imageName", ConstantUtil.harborAddress + "/softwise/" + vueTplEntity.getContainer().getImageName());
        jenkinsfileMapper.put("kubeconfig", ConstantUtil.internalKubeConfig);
        jenkinsfileMapper.put("allImageName", ConstantUtil.allImageNameBuild + vueTplEntity.getContainer().getImageName());
        jenkinsfileMapper.put("tagCommand", tagsCommand);
        jenkinsfileMapper.put("env", "test");
        jenkinsfileMapper.put("cluster", "internal");
        jenkinsfileMapper.put("k8sYamlDir", testYamlDir);
        jenkinsfileMapper.put("repoCredential", "internal-harbor");
    }

    private void replaceJenkinsfileProd() {
        FreemakerTool.generateFile(loopTemplateOutputPath + "Jenkinsfile",
                "Jenkinsfile.vue.v2.ftl",
                jenkinsfileMapper);
    }

    private void replaceJenkinsfileTest() {
        FreemakerTool.generateFile(loopTemplateOutputPath + "Jenkinsfile-test",
                "Jenkinsfile.vue.v2.ftl",
                jenkinsfileMapper);
    }

    private void prepareK8sFilesProd() {
        kubeYamlMapper.put("deployName", vueTplEntity.getK8s().getDeployName());
        kubeYamlMapper.put("kubesphereDescription", vueTplEntity.getDingMsg());
        kubeYamlMapper.put("namespace", vueTplEntity.getK8s().getNamespace());
        kubeYamlMapper.put("ingressName", vueTplEntity.getK8s().getDeployName());
        kubeYamlMapper.put("svcName", vueTplEntity.getK8s().getDeployName());

        if (vueTplEntity.getK8s().getIngress().getEnable()) {
            kubeYamlMapper.put("domain", vueTplEntity.getK8s().getIngress().getDomainProd());
            if (vueTplEntity.getK8s().getIngress().getPrefixProd().equals("/")) {
                kubeYamlMapper.put("path", vueTplEntity.getK8s().getIngress().getPrefixProd());
                kubeYamlMapper.put("nginxRewrite", "");
            } else {
                kubeYamlMapper.put("path", vueTplEntity.getK8s().getIngress().getPrefixProd() + "(/|$)(.*)");
                kubeYamlMapper.put("nginxRewrite", "nginx.ingress.kubernetes.io/rewrite-target: /$2");
            }
        }
    }

    private void prepareK8sFilesTest() {
        if (vueTplEntity.getK8s().getIngress().getEnable()) {
            kubeYamlMapper.put("domain", vueTplEntity.getK8s().getIngress().getDomainTest());
            if (vueTplEntity.getK8s().getIngress().getPrefixTest().equals("/")) {
                kubeYamlMapper.put("path", vueTplEntity.getK8s().getIngress().getPrefixTest());
                kubeYamlMapper.put("nginxRewrite", "");
            } else {
                kubeYamlMapper.put("path", vueTplEntity.getK8s().getIngress().getPrefixTest() + "(/|$)(.*)");
                kubeYamlMapper.put("nginxRewrite", "nginx.ingress.kubernetes.io/rewrite-target: /$2");
            }
        }
    }


    private void replaceK8sFilesProd() {
        String k8sFileOutputPath = loopTemplateOutputPath + "kube-yaml" + "/";
        String prodFilePath = k8sFileOutputPath + "prod/";

        if (vueTplEntity.getK8s().getIngress().getEnable()) {
            // ingress文件
            FreemakerTool.generateFile(prodFilePath + vueTplEntity.getK8s().getDeployName() + "-ingress.yaml",
                    "ingress.vue.ftl",
                    kubeYamlMapper);
        }
        // deployment文件
        FreemakerTool.generateFile(prodFilePath + vueTplEntity.getK8s().getDeployName() + "-deploy.yaml",
                "deployment.vue.ftl",
                kubeYamlMapper);
        // svc文件
        FreemakerTool.generateFile(prodFilePath + vueTplEntity.getK8s().getDeployName() + "-svc.yaml",
                "svc.vue.ftl",
                kubeYamlMapper);
    }

    private void replaceK8sFilesTest() {
        String k8sFileOutputPath = loopTemplateOutputPath + "kube-yaml" + "/";
        String testFilePath = k8sFileOutputPath + "test/";

        if (vueTplEntity.getK8s().getIngress().getEnable()) {
            FreemakerTool.generateFile(testFilePath + vueTplEntity.getK8s().getDeployName() + "-ingress.yaml",
                    "ingress.vue.ftl",
                    kubeYamlMapper);
        }
        // deployment文件
        FreemakerTool.generateFile(testFilePath + vueTplEntity.getK8s().getDeployName() + "-deploy.yaml",
                "deployment.vue.ftl",
                kubeYamlMapper);
        // svc文件
        FreemakerTool.generateFile(testFilePath + vueTplEntity.getK8s().getDeployName() + "-svc.yaml",
                "svc.vue.ftl",
                kubeYamlMapper);
    }

}